package ar.fiuba.tp7552.buildadmin.service.impl;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;

import org.springframework.transaction.annotation.Transactional;

import ar.fiuba.tp7552.buildadmin.dao.CobroPlanDao;
import ar.fiuba.tp7552.buildadmin.dao.LiquidacionPlanDao;
import ar.fiuba.tp7552.buildadmin.dao.PlanDao;
import ar.fiuba.tp7552.buildadmin.model.BusinessException;
import ar.fiuba.tp7552.buildadmin.model.builds.Edificio;
import ar.fiuba.tp7552.buildadmin.model.builds.Propiedad;
import ar.fiuba.tp7552.buildadmin.model.builds.Responsable;
import ar.fiuba.tp7552.buildadmin.model.expensas.TipoExpensa;
import ar.fiuba.tp7552.buildadmin.model.planes.CobroPlan;
import ar.fiuba.tp7552.buildadmin.model.planes.LiquidacionPlan;
import ar.fiuba.tp7552.buildadmin.model.planes.LiquidacionPlanFinder;
import ar.fiuba.tp7552.buildadmin.model.planes.Plan;
import ar.fiuba.tp7552.buildadmin.service.PlanService;
import ar.fiuba.tp7552.buildadmin.webactions.expensas.DetalleCobro;

@Transactional(rollbackFor = BusinessException.class)
public class PlanServiceImpl implements PlanService {

	private PlanDao planDao;
	private LiquidacionPlanDao liquidacionPlanDao;
	private CobroPlanDao cobroPlanDao;

	public PlanServiceImpl(PlanDao planDao,
			LiquidacionPlanDao liquidacionPlanDao, CobroPlanDao cobroPlanDao) {
		super();
		this.planDao = planDao;
		this.liquidacionPlanDao = liquidacionPlanDao;
		this.cobroPlanDao = cobroPlanDao;
	}

	public Plan createPlan(Responsable responsable,
			Collection<Propiedad> propiedades, Date fecha, BigDecimal monto,
			TipoExpensa tipoExpensa, int cuotas) throws BusinessException {
		Plan plan = new Plan();
		plan.crear(responsable, propiedades, fecha, monto, tipoExpensa, cuotas);
		planDao.save(plan);
		return plan;
	}

	@Override
	public void liquidar(Edificio edificio) {
		Collection<Plan> planes = planDao.find(edificio);
		for (Plan plan : planes) {
			try {
				LiquidacionPlan liq = plan.liquidar(false);
				if (liq != null) {
					liquidacionPlanDao.save(liq);
				}
			} catch (BusinessException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public DetalleCobro detalleCobro(Plan plan, Date fechaCobro)
			throws BusinessException {
		return plan.calcularDetalle(fechaCobro,
				(LiquidacionPlanFinder) liquidacionPlanDao);
	}

	@Override
	public CobroPlan registrarCobro(Plan plan, Date fechaCobro,
			BigDecimal monto, String comprobante) throws BusinessException {
		CobroPlan cobro = plan.registrarCobro(monto, fechaCobro, comprobante,
				(LiquidacionPlanFinder) liquidacionPlanDao);
		cobroPlanDao.save(cobro);
		return cobro;
	}

	@Override
	public Collection<Plan> getAll() {
		return planDao.getAll();
	}

	@Override
	public Plan get(Long id) {
		return planDao.get(id);
	}

	@Override
	public void update(Plan plan) {
		planDao.update(plan);
	}

	@Override
	public void delete(Plan plan) {
		planDao.remove(plan.getId());
	}

	@Override
	public void revertirCobro(CobroPlan cobro) {
		Plan plan = cobro.getPlan();
		plan.revertirCobro(cobro);
		this.cobroPlanDao.remove(cobro.getId());
	}

	@Override
	public void consolidar(CobroPlan cobro, String comprobante) {
		cobro.consolidar(comprobante);
		this.cobroPlanDao.update(cobro);
	}
}